<!--分配权限-->
<script setup>
import { onMounted, nextTick } from "vue";
import useDialog from "@/hooks/use-dialog";
import { throttle } from "lodash-es";
import { ElMessage, ElMessageBox } from "element-plus";
import { treeMenuPermitMockApi } from "@/api/mock-js/system/menu-permit-api";
import { getPermissionListByRoleIdMockApi } from "@/api/mock-js/system/role-api";

defineOptions({
  name: "DialogRolePermission",
});

onMounted(async () => {
  await renderTable();
  await nextTick();
  await getRolePermissionsByRoleId(formData.roleId);
});
const modelValue = defineModel({ type: Boolean });

const emit = defineEmits(["on-close"]);

const treeProps = {
  children: "children",
  value: "id",
  label: "permissionName",
};
const formData = reactive({
  roleId: undefined,
  permissionIds: [],
});

const { loading, title, preTitle, loadData, save, readClose, setInitData } =
  useDialog(emit, formData, modelValue);
const treeRef = ref();

const treeData = ref([]);
const renderTable = async () => {
  try {
    const res = await treeMenuPermitMockApi();
    treeData.value = res.data;
  } catch (e) {
  } finally {
  }
};
// 根据roleId[]获取角色已分配的权限
const rolePermissionList = ref([]);
const getRolePermissionsByRoleId = async (roleId) => {
  try {
    const res = await getPermissionListByRoleIdMockApi({ roleIds: [roleId] });
    rolePermissionList.value = res.data;
    const _checkList = res.data.map(({ id }) => id);
    treeRef.value.setCheckedKeys(_checkList);
  } catch (e) {
  } finally {
  }
};

// 递归选中
const handleParentNode = (id) => {
  const _node = treeRef.value?.getNode(id);
  if (!_node) return;
  if (_node.data.parentId) {
    treeRef.value.setChecked(_node.data.parentId, true);
    if (_node.parent.data.parentId) {
      handleParentNode(_node.parent.data.id);
    }
  }
};
/* 控制选中
 *  父级选中/取消,所有子级以及子级的子级都选中/取消
 *  子级选中,其所有直属父级都被选中
 *  取消子级不会影响父级。
 * */
const handleCheckNode = async (val) => {
  const _node = treeRef.value?.getNode(val.id);
  if (!_node) return;
  // 子级被选中，会将父级和祖父级也选中，否则不选中。
  if (_node?.data?.parentId && _node.checked && !_node?.parent?.checked) {
    handleParentNode(val.id);
  }
  if (_node?.data?.children?.length) {
    for (const item of _node.data.children) {
      // 设置子级 选中/取消选中
      treeRef.value.setChecked(item.id, _node.checked);
      // 递归设置孙子级的选中/取消
      let _promises = [];
      if (item?.children?.length) {
        _promises.push(handleCheckNode(item));
      }
      await Promise.all(_promises);
    }
  }
};
// 保存
const handleSave = throttle(() => {
  ElMessageBox.confirm(`此操作将修改角色的权限信息, 是否继续?`, "保存提示")
    .then(async () => {
      loadData.loading = true;
      try {
        // await 保存方法
        ElMessage.success(
          "(仅做模板展示，不会修改数据)角色权限分配成功！将在重新登录后生效!"
        );
        emit("on-close");
        readClose?.();
      } catch (e) {
      } finally {
        loadData.loading = false;
      }
    })
    .catch(() => {
      // 点击取消后 关闭loading
      loadData.loading = false;
    });
}, 1000);
defineExpose({
  preTitle,
  title,
  formData,
  setInitData,
});
</script>
<template>
  <DialogForm class="dialog-role-permission" :model-value="modelValue" :title="`分配权限-${title}`" :id="formData.roleId"
    hide-flag align-center width="420px" :loading="loadData.loading" @on-save="handleSave" @on-close="readClose"
    @on-cancel="readClose">
    <ElTree class="role-menu-tree" :data="treeData" v-loading="loading" show-checkbox check-strictly default-expand-all
      node-key="id" ref="treeRef" :props="treeProps" @check="handleCheckNode" />
  </DialogForm>
</template>

<style lang="scss">
.dialog-role-permission {
  .el-dialog__body {
    padding-top: 0;
  }

  .el-tree {
    height: 80vh;
    max-height: calc(100vh - 160px);
    border: 1px solid var(--el-border-color);
    border-radius: 4px;
    overflow: auto;
  }
}
</style>
